接下來要說的是關於React的一些優化方法
useMemo 和 useCallback 是 React 中的兩個優化 Hook,它們的作用是避免不必要的計算和函數重新創建,從而提升性能。
useMemo 用於記憶一個計算結果,只有當依賴項改變時,才會重新進行計算。這在有複雜計算或需要優化性能的場景中非常有用。
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState('');
// 這是一個耗時的計算函數
const expensiveCalculation = (num) => {
console.log('進行了計算');
for (let i = 0; i < 1000000000; i++) {} // 模擬耗時計算
return num * 2;
};
// 每次渲染都會重新計算
const result = expensiveCalculation(count);
return (
<div>
<h1>Expensive Calculation Result: {result}</h1>
<button onClick={() => setCount(count + 1)}>增加計數: {count}</button>
<input value={input} onChange={(e) => setInput(e.target.value)} />
</div>
);
}
export default App;
在這個範例中,每次輸入框的值改變時,整個組件都會重新渲染,並且 expensiveCalculation 都會重新計算,這導致不必要的性能浪費。
為了避免這種不必要的計算,我們可以使用 useMemo。useMemo 會記憶某次計算的結果,只有當依賴項(這裡是 count)改變時,才會重新執行計算。
import React, { useState, useMemo } from 'react';
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState('');
const expensiveCalculation = (num) => {
console.log('進行了計算');
for (let i = 0; i < 1000000000; i++) {} // 模擬耗時計算
return num * 2;
};
// 只有當 count 改變時才重新計算
const result = useMemo(() => expensiveCalculation(count), [count]);
return (
<div>
<h1>Expensive Calculation Result: {result}</h1>
<button onClick={() => setCount(count + 1)}>增加計數: {count}</button>
<input value={input} onChange={(e) => setInput(e.target.value)} />
</div>
);
}
export default App;
在這個優化範例中,我們使用 useMemo 來記憶 expensiveCalculation 的結果。只有當 count 改變時,useMemo 才會重新執行計算,這樣可以避免在輸入框每次輸入時重新進行不必要的計算。
useCallback 用來記憶一個回調函數,當依賴項不變時,它會返回同一個函數實例。這在將回調函數傳遞給子組件時非常有用,避免每次父組件渲染時,子組件重新渲染。
import React, { useState } from 'react';
const Button = ({ onClick }) => {
console.log('Button 組件重新渲染'); // 用來檢查 Button 是否重新渲染
return <button onClick={onClick}>點擊我</button>;
};
function App() {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log('按鈕被點擊');
};
return (
<div>
<h1>計數: {count}</h1>
<Button onClick={handleClick} />
<button onClick={() => setCount(count + 1)}>增加計數</button>
</div>
);
}
export default App;
在這個範例中,每次 App 組件重新渲染時,handleClick 函數都會重新創建,導致子組件 Button 每次也重新渲染。
原因就跟上面一樣由狀態變更導致的重覆觸發。
import React, { useState, useCallback } from 'react';
// 使用 React.memo 優化 Button 組件
const Button = React.memo(({ handleClick }) => {
console.log('Button 組件重新渲染');
return <button onClick={handleClick}>點擊我</button>;
});
function App() {
const [count, setCount] = useState(0);
// 使用 useCallback 記憶 handleClick 函數
const handleClick = useCallback(() => {
console.log('按鈕點擊');
}, []); // 這裡的依賴是空數組,表示 handleClick 永遠不會變化
return (
<div>
<h1>計數: {count}</h1>
<Button handleClick={handleClick} />
<button onClick={() => setCount(count + 1)}>增加計數</button>
</div>
);
}
export default App;
使用 useCallback,我們將 handleClick 函數記憶起來,這樣當 App 組件重新渲染時,Button 組件不會因為 handleClick 的改變而重新渲染。
然後裡面有熟悉的[]
依賴向,如果在其中填入count他就會被重新渲染了,可以很有效的控管哪些項目觸發時需要被渲染,哪些不需要被渲染
今天就到這了,謝謝